package com.ecommerce.order.service.impl;

import com.ecommerce.order.client.ProductServiceClient;
import com.ecommerce.order.client.UserServiceClient;
import com.ecommerce.order.dto.OrderCreateRequest;
import com.ecommerce.order.dto.OrderMapper;
import com.ecommerce.order.dto.OrderPageResponse;
import com.ecommerce.order.dto.OrderResponse;
import com.ecommerce.order.dto.OrderUpdateStatusRequest;
import com.ecommerce.order.dto.ProductResponse;
import com.ecommerce.order.dto.UserResponse;
import com.ecommerce.order.entity.Order;
import com.ecommerce.order.entity.OrderItem;
import com.ecommerce.order.exception.BusinessException;
import com.ecommerce.order.repository.OrderItemRepository;
import com.ecommerce.order.repository.OrderRepository;
import com.ecommerce.order.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderServiceImpl implements OrderService {

    private final OrderRepository orderRepository;
    private final OrderItemRepository orderItemRepository;
    private final OrderMapper orderMapper;
    private final ProductServiceClient productServiceClient;
    private final UserServiceClient userServiceClient;

    @Override
    @Transactional
    public OrderResponse createOrder(OrderCreateRequest createRequest, Long userId, String username) {
        log.info("创建订单, 用户ID: {}, 用户名: {}", userId, username);
        log.debug("创建订单请求详情: {}", createRequest);
        try {

        // 验证用户是否存在 - 简化验证逻辑，因为用户身份已经通过网关认证
        log.info("创建订单 - 用户ID: {}, 用户名: {}", userId, username);
        if (userId == null || userId <= 0) {
            log.error("无效的用户ID: {}", userId);
            throw new RuntimeException("无效的用户ID");
        }
        
        // 验证请求参数
        if (createRequest == null) {
            log.error("创建订单请求为空");
            throw new RuntimeException("订单请求不能为空");
        }
        if (createRequest.getItems() == null || createRequest.getItems().isEmpty()) {
            log.error("订单项为空");
            throw new RuntimeException("订单项不能为空");
        }
        if (createRequest.getReceiverName() == null || createRequest.getReceiverName().trim().isEmpty()) {
            log.error("收货人姓名为空");
            throw new RuntimeException("收货人姓名不能为空");
        }

        // 创建订单
        Order order = new Order();
        order.setOrderNo(generateOrderNo());
        order.setUserId(userId);
        order.setUsername(username);
        order.setStatus(0); // 待付款
        order.setReceiverName(createRequest.getReceiverName());
        order.setReceiverPhone(createRequest.getReceiverPhone());
        order.setReceiverAddress(createRequest.getReceiverAddress());
        order.setRemark(createRequest.getRemark());

        // 计算订单总金额
        final BigDecimal[] totalAmount = {BigDecimal.ZERO};
        log.info("开始处理订单项，共 {} 个", createRequest.getItems().size());
        
        List<OrderItem> orderItems = createRequest.getItems().stream().map(item -> {
            log.info("处理订单项 - 产品ID: {}, 数量: {}, 价格: {}", item.getProductId(), item.getQuantity(), item.getPrice());
            
            // 获取产品信息
            ProductResponse product = null;
            try {
                product = productServiceClient.getProductById(item.getProductId());
                if (product == null) {
                    log.error("产品不存在: {}", item.getProductId());
                    throw new RuntimeException("产品不存在: " + item.getProductId());
                }
                log.info("成功获取产品信息: {}", product.getName());
            } catch (Exception e) {
                log.error("获取产品信息失败 - 异常类型: {}, 错误信息: {}", e.getClass().getSimpleName(), e.getMessage(), e);
                // 使用前端传递的价格
                product = new ProductResponse();
                product.setId(item.getProductId());
                product.setName("产品" + item.getProductId());
                product.setPrice(item.getPrice() != null ? item.getPrice() : BigDecimal.ZERO);
            }

            // 创建订单项
            OrderItem orderItem = new OrderItem();
            orderItem.setProductId(item.getProductId());
            orderItem.setProductName(product.getName());
            orderItem.setProductImage(""); // ProductResponse没有image字段，暂时设为空字符串
            orderItem.setProductPrice(product.getPrice());
            orderItem.setQuantity(item.getQuantity());
            
            // 使用产品价格计算小计
            BigDecimal itemPrice = product.getPrice() != null ? product.getPrice() : BigDecimal.ZERO;
            BigDecimal subtotal = itemPrice.multiply(new BigDecimal(item.getQuantity()));
            orderItem.setSubtotal(subtotal);

            // 计算总金额
            totalAmount[0] = totalAmount[0].add(subtotal);

            return orderItem;
        }).collect(Collectors.toList());

        // 设置订单金额
        order.setTotalAmount(totalAmount[0]);
        order.setShippingFee(BigDecimal.ZERO); // 运费计算逻辑
        order.setPayAmount(totalAmount[0].add(order.getShippingFee()));
        
        log.info("订单金额设置完成 - 总金额: {}, 运费: {}, 实付金额: {}", totalAmount[0], order.getShippingFee(), order.getPayAmount());

        // 保存订单
        log.info("开始保存订单...");
        order = orderRepository.save(order);
        log.info("订单保存成功，订单ID: {}", order.getId());

        // 保存订单项
        log.info("开始保存订单项，共 {} 个", orderItems.size());
        final Long orderId = order.getId();
        List<OrderItem> savedOrderItems = orderItems.stream().peek(item -> {
            item.setOrderId(orderId);
        }).collect(Collectors.toList());
        orderItemRepository.saveAll(savedOrderItems);
        log.info("订单项保存成功");

        // 返回订单响应
        OrderResponse response = orderMapper.entityToResponseDto(order);
        response.setStatusText(orderMapper.getStatusText(order.getStatus()));
        response.setPaymentMethodText(orderMapper.getPaymentMethodText(order.getPaymentMethod()));
        response.setItems(orderMapper.orderItemEntityToResponseDtoList(savedOrderItems));

        log.info("订单创建成功, 订单ID: {}, 订单编号: {}", order.getId(), order.getOrderNo());
        return response;
        } catch (Exception e) {
            log.error("创建订单失败 - 异常类型: {}, 错误信息: {}, 堆栈跟踪: ", 
                     e.getClass().getSimpleName(), e.getMessage(), e);
            throw new BusinessException("创建订单失败: " + e.getMessage(), e);
        }
    }

    @Override
    public OrderResponse getOrderById(Long orderId, Long userId) {
        log.info("获取订单详情, 订单ID: {}, 用户ID: {}", orderId, userId);

        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));

        // 验证订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            throw new RuntimeException("无权访问该订单");
        }

        // 获取订单项
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(orderId);

        // 构建响应
        OrderResponse response = orderMapper.entityToResponseDto(order);
        response.setStatusText(orderMapper.getStatusText(order.getStatus()));
        response.setPaymentMethodText(orderMapper.getPaymentMethodText(order.getPaymentMethod()));
        response.setItems(orderMapper.orderItemEntityToResponseDtoList(orderItems));

        return response;
    }

    @Override
    public OrderResponse getByOrderNo(String orderNo, Long userId) {
        log.info("根据订单编号获取订单详情, 订单编号: {}, 用户ID: {}", orderNo, userId);

        Order order = orderRepository.findByOrderNo(orderNo)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderNo));

        // 验证订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            throw new RuntimeException("无权访问该订单");
        }

        // 获取订单项
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(order.getId());

        // 构建响应
        OrderResponse response = orderMapper.entityToResponseDto(order);
        response.setStatusText(orderMapper.getStatusText(order.getStatus()));
        response.setPaymentMethodText(orderMapper.getPaymentMethodText(order.getPaymentMethod()));
        response.setItems(orderMapper.orderItemEntityToResponseDtoList(orderItems));

        return response;
    }

    @Override
    public OrderPageResponse getOrdersByUserId(Long userId, Integer page, Integer size) {
        log.info("分页获取用户订单列表, 用户ID: {}, 页码: {}, 每页大小: {}", userId, page, size);

        Pageable pageable = PageRequest.of(page - 1, size);
        Page<Order> orderPage = orderRepository.findByUserId(userId, pageable);

        List<OrderResponse> orders = orderPage.getContent().stream()
                .map(order -> {
                    List<OrderItem> orderItems = orderItemRepository.findByOrderId(order.getId());
                    OrderResponse response = orderMapper.entityToResponseDto(order);
                    response.setStatusText(orderMapper.getStatusText(order.getStatus()));
                    response.setPaymentMethodText(orderMapper.getPaymentMethodText(order.getPaymentMethod()));
                    response.setItems(orderMapper.orderItemEntityToResponseDtoList(orderItems));
                    return response;
                })
                .collect(Collectors.toList());

        OrderPageResponse response = new OrderPageResponse();
        response.setOrders(orders);
        response.setTotal(orderPage.getTotalElements());
        response.setPage(page);
        response.setSize(size);
        response.setTotalPages(orderPage.getTotalPages());

        return response;
    }

    @Override
    public OrderPageResponse getOrdersByUserIdAndStatus(Long userId, Integer status, Integer page, Integer size) {
        log.info("根据状态获取用户订单列表, 用户ID: {}, 状态: {}, 页码: {}, 每页大小: {}", userId, status, page, size);

        Pageable pageable = PageRequest.of(page - 1, size);
        Page<Order> orderPage = orderRepository.findByUserIdAndStatus(userId, status, pageable);

        List<OrderResponse> orders = orderPage.getContent().stream()
                .map(order -> {
                    List<OrderItem> orderItems = orderItemRepository.findByOrderId(order.getId());
                    OrderResponse response = orderMapper.entityToResponseDto(order);
                    response.setStatusText(orderMapper.getStatusText(order.getStatus()));
                    response.setPaymentMethodText(orderMapper.getPaymentMethodText(order.getPaymentMethod()));
                    response.setItems(orderMapper.orderItemEntityToResponseDtoList(orderItems));
                    return response;
                })
                .collect(Collectors.toList());

        OrderPageResponse response = new OrderPageResponse();
        response.setOrders(orders);
        response.setTotal(orderPage.getTotalElements());
        response.setPage(page);
        response.setSize(size);
        response.setTotalPages(orderPage.getTotalPages());

        return response;
    }

    @Override
    @Transactional
    public OrderResponse updateOrderStatus(Long orderId, OrderUpdateStatusRequest updateRequest, Long userId) {
        log.info("更新订单状态, 订单ID: {}, 状态: {}, 用户ID: {}", orderId, updateRequest.getStatus(), userId);

        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));

        // 验证订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            throw new RuntimeException("无权修改该订单");
        }

        // 更新订单状态
        order.setStatus(updateRequest.getStatus());

        // 根据状态更新时间
        switch (updateRequest.getStatus()) {
            case 1: // 待发货
                order.setPaymentTime(LocalDateTime.now());
                break;
            case 2: // 已发货
                order.setShippingTime(LocalDateTime.now());
                break;
            case 3: // 已完成
                order.setCompletionTime(LocalDateTime.now());
                break;
            default:
                break;
        }

        order = orderRepository.save(order);

        // 获取订单项
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(orderId);

        // 构建响应
        OrderResponse response = orderMapper.entityToResponseDto(order);
        response.setItems(orderMapper.orderItemEntityToResponseDtoList(orderItems));

        log.info("订单状态更新成功, 订单ID: {}, 新状态: {}", orderId, updateRequest.getStatus());
        return response;
    }

    @Override
    @Transactional
    public OrderResponse cancelOrder(Long orderId, Long userId) {
        log.info("取消订单, 订单ID: {}, 用户ID: {}", orderId, userId);

        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));

        // 验证订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            throw new RuntimeException("无权取消该订单");
        }

        // 验证订单状态是否可以取消
        if (order.getStatus() != 0) {
            throw new RuntimeException("只有待付款的订单才能取消");
        }

        // 更新订单状态
        order.setStatus(4); // 已取消
        order = orderRepository.save(order);

        // 获取订单项
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(orderId);

        // 构建响应
        OrderResponse response = orderMapper.entityToResponseDto(order);
        response.setItems(orderMapper.orderItemEntityToResponseDtoList(orderItems));

        log.info("订单取消成功, 订单ID: {}", orderId);
        return response;
    }

    @Override
    @Transactional
    public void deleteOrder(Long orderId, Long userId) {
        log.info("删除订单, 订单ID: {}, 用户ID: {}", orderId, userId);

        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));

        // 验证订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            throw new RuntimeException("无权删除该订单");
        }

        // 验证订单状态是否可以删除
        if (order.getStatus() != 3 && order.getStatus() != 4) {
            throw new RuntimeException("只有已完成或已取消的订单才能删除");
        }

        // 删除订单项
        orderItemRepository.deleteByOrderId(orderId);

        // 删除订单
        orderRepository.deleteById(orderId);

        log.info("订单删除成功, 订单ID: {}", orderId);
    }

    @Override
    @Transactional
    public OrderResponse payOrder(Long orderId, Integer paymentMethod, Long userId) {
        log.info("支付订单, 订单ID: {}, 支付方式: {}, 用户ID: {}", orderId, paymentMethod, userId);

        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));

        // 验证订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            throw new RuntimeException("无权支付该订单");
        }

        // 验证订单状态是否可以支付
        if (order.getStatus() != 0) {
            throw new RuntimeException("只有待付款的订单才能支付");
        }

        // 更新订单状态
        order.setStatus(1); // 待发货
        order.setPaymentMethod(paymentMethod);
        order.setPaymentTime(LocalDateTime.now());
        order = orderRepository.save(order);

        // 获取订单项
        List<OrderItem> orderItems = orderItemRepository.findByOrderId(orderId);

        // 减少库存
        for (OrderItem orderItem : orderItems) {
            try {
                productServiceClient.reduceStock(orderItem.getProductId(), orderItem.getQuantity());
            } catch (Exception e) {
                log.error("减少库存失败, 产品ID: {}, 数量: {}", orderItem.getProductId(), orderItem.getQuantity(), e);
                // 可以考虑回滚订单状态
                throw new RuntimeException("支付失败，库存不足");
            }
        }

        // 构建响应
        OrderResponse response = orderMapper.entityToResponseDto(order);
        response.setItems(orderMapper.orderItemEntityToResponseDtoList(orderItems));

        log.info("订单支付成功, 订单ID: {}", orderId);
        return response;
    }

    /**
     * 生成订单编号
     * @return 订单编号
     */
    private String generateOrderNo() {
        return "ORD" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }
}